package cn.com.hhrcw.enterprise.web;

import cn.com.hhrcw.enterprise.params.SsDeliveryParam;
import cn.com.hhrcw.enterprise.params.SsSessionParams;
import cn.com.hhrcw.enterprise.service.EnterpriseService;
import cn.com.hhrcw.enterprise.vo.*;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 专场
 *
 * @author jiangdong
 * @since 2020-10-29
 */
@RestController
@Slf4j
@RequestMapping("/en/ssSession")
@Api(tags = "专场-专场本场")
@Validated
public class EnSsSessionController extends JeecgController<SsSession, ISsSessionService> {

    @Autowired
    private ISsSessionService ssSessionService;

    @Autowired
    private EnSsSessionConvert enSsSessionConvert;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private EnOpJobConvert jobConvert;

    @Autowired
    EnterpriseService enterpriseService;

    @Autowired
    private IPiInfoService piInfoService;

    @Autowired
    private ICvUserEduInfoService eduInfoService;

    @Autowired
    private EnCvUserEduInfoConvert eduInfoConvert;

    @Autowired
    private EnPiInfoConvert enPiInfoConvert;

    @Autowired
    private ICvUserWorkInfoService workInfoService;

    @Autowired
    private EnCvUserWorkInfoConvert workInfoConvert;

    @Autowired
    private ICvWorkIntentionService workIntentionService;

    @Autowired
    private EnCvWorkIntentionConvert workIntentionConvert;

    @Autowired
    private ISysUserDepartService userDepartService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    EnEnInfoConvert enInfoConvert;

    @Autowired
    private IEnInfoService enInfoService;

    @Autowired
    IOpEntryHistoryService entryHistoryService;

    @Autowired
    private EnOpDeliveryHistoryConvert deliveryHistoryConvert;

    @Autowired
    private EnOpEntryHistoryConvert entryHistoryConvert;

    @Autowired
    private IEnContactsService enContactsService;

    @Autowired
    EnEnContactsConvert contactsConvert;

    @Autowired
    private EnOpInterviewHistoryConvert interviewHistoryConvert;

    @Autowired
    private IOpInterviewContactService contactService;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    EnCvResumeConvert resumeConvert;

    /**
     * 专场招聘-招聘数据
     *
     * @param ssId 专场id
     * @return
     */
    @GetMapping(value = "/getDataInfo")
    public Result<SsDataInfoVO> getDataInfo(String ssId) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        SsDataInfoVO infoVO = enterpriseService.getDatInfo(ssId, userDepart.getDepId());
        return Result.ok(infoVO);
    }

    /**
     * 专场招聘-专场列表
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/list")
    @AutoLog(logType = 2, ty = "visit", value = "专场列表查询")
    @ApiOperation(value = "分页列表查询", notes = "分页列表查询")
    @PermissionData
    public Result<Page<SsSessionVO>> list(SsSessionParams params, HttpServletRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getCompanyId, userDepart.getDepId()).eq(OpJob::getBsType, 1).list();
        if (!CollectionUtils.isEmpty(jobs)) {
            List<String> ids = new ArrayList<>();
            jobs.forEach(e -> {
                ids.add(e.getBsId());
            });
            if (!CollectionUtils.isEmpty(ids)) {
                LambdaQueryWrapper<SsSession> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SsSession::getDelFlag, false).in(SsSession::getId, ids);
                Date date = new Date();
                switch (params.getTimeState()) {
                    case 1:
                        //进行中
                        queryWrapper.le(SsSession::getStartTime, date).gt(SsSession::getEndTime, date);
                        break;
                    case 2:
                        //未开始
                        queryWrapper.gt(SsSession::getStartTime, date);
                        break;
                    case 3:
                        //已结束
                        queryWrapper.lt(SsSession::getEndTime, date);
                        break;
                    default:
                        break;
                }
                IPage<SsSession> page = ssSessionService.page(params.page(), queryWrapper);
                //分页结果转换器
                Function<SsSession, SsSessionVO> fun = ssSession -> {
                    SsSessionVO vo = enSsSessionConvert.toVO(ssSession);

                    //职位数量
                    LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
                    jobQuery.eq(OpJob::getDelFlag, false).eq(OpJob::getBsType, 1).eq(OpJob::getBsId, vo.getId()).eq(OpJob::getCompanyId, userDepart.getDepId()).select(OpJob::getId);
                    List<OpJob> job = jobService.list(jobQuery);
                    if (!CollectionUtils.isEmpty(job)) {
                        vo.setJobCount(job.size());
                        List<String> jobIds = new ArrayList<>();
                        job.forEach(e -> {
                            jobIds.add(e.getId());
                        });
                        LambdaQueryWrapper<OpDeliveryHistory> historyQuery = new LambdaQueryWrapper<>();
                        historyQuery.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds);
                        int deliveryCount = deliveryHistoryService.count(historyQuery);
                        vo.setUserCount(deliveryCount);
                    }

                    long time = System.currentTimeMillis();
                    if (ssSession.getStartTime().getTime() <= time && ssSession.getEndTime().getTime() > time) {//进行中
                        vo.setTimeState(1);
                    } else if (ssSession.getStartTime().getTime() > time) {//未开始
                        vo.setTimeState(2);
                    } else if (ssSession.getEndTime().getTime() < time) {//已结束
                        vo.setTimeState(3);
                    }
                    return vo;
                };
                return Result.ok((Page) page.convert(fun));
            }
        }
        return Result.ok(new Page<>());
    }

    /**
     * 专场招聘-职位
     *
     * @param params  专场id必传
     * @param request
     * @return
     */
    @GetMapping("/getJobList")
    @AutoLog(logType = 2, ty = "visit", value = "专场职位查询")
    public Result<Page<OpJobVO>> getJobListBySessionId(SsSessionParams params, HttpServletRequest request) {
        LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getJobName())) {
            jobQuery.like(OpJob::getJobName, params.getJobName());
        }
        jobQuery.eq(OpJob::getDelFlag, false).eq(OpJob::getBsType, 1).eq(OpJob::getBsId, params.getId());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        jobQuery.eq(OpJob::getCompanyId, userDepart.getDepId());
        IPage<OpJob> page = jobService.page(params.page(), jobQuery);
        Function<OpJob, OpJobVO> fun = job -> {
            OpJobVO vo = jobConvert.toVO(job);
            //已招聘人数
            LambdaQueryWrapper<OpDeliveryHistory> historyQuery = new LambdaQueryWrapper<>();
            historyQuery.eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getJobId, vo.getId()).eq(OpDeliveryHistory::getState, 7);
            int countAlready = deliveryHistoryService.count(historyQuery);
            vo.setAlreadyCount(countAlready);

            LambdaQueryWrapper<OpDeliveryHistory> notRead = new LambdaQueryWrapper<>();
            notRead.eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getJobId, vo.getId()).eq(OpDeliveryHistory::getState, 0);
            int notReadCount = deliveryHistoryService.count(notRead);
            vo.setNotReadCount(notReadCount);

            LambdaQueryWrapper<OpDeliveryHistory> stepQuery = new LambdaQueryWrapper<>();
            stepQuery.eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getJobId, vo.getId()).eq(OpDeliveryHistory::getState, 4);
            int stepCount = deliveryHistoryService.count(stepQuery);
            vo.setStepCount(stepCount);
            return vo;
        };
        return Result.ok((Page) page.convert(fun));
    }

    /**
     * 专场招聘-人才
     *
     * @param params
     * @param request
     * @return
     */
    @GetMapping("/getUserList")
    @AutoLog(logType = 2, ty = "visit", value = "专场人才查询")
    public Result<Page<SsUserInfoVO>> getUserList(SsDeliveryParam params, HttpServletRequest request) {
        LambdaQueryWrapper<OpJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart depart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        jobLambdaQueryWrapper.eq(OpJob::getDelFlag, false).eq(OpJob::getCompanyId, depart.getDepId());
        //专场条件
        jobLambdaQueryWrapper.eq(OpJob::getBsType, 1).eq(OpJob::getBsId, params.getSsId());
        if (StringUtils.isNotBlank(params.getJobName())) {
            jobLambdaQueryWrapper.like(OpJob::getJobName, params.getJobName());
        }
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        jobLambdaQueryWrapper.eq(OpJob::getCompanyId, userDepart.getDepId());
        List<OpJob> jobs = jobService.list(jobLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(jobs)) {
            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            LambdaQueryWrapper<OpDeliveryHistory> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds);

            if (!createGetUserListWrapper(queryWrapper, params)) {
                return Result.ok(new Page<>());
            }
            queryWrapper.notIn(OpDeliveryHistory::getState, new Integer[]{7});
            IPage<OpDeliveryHistory> page = deliveryHistoryService.page(params.page(), queryWrapper);
            Function<OpDeliveryHistory, SsUserInfoVO> function = opDeliveryHistory -> {
                SsUserInfoVO vo = new SsUserInfoVO();
                vo.setDataId(opDeliveryHistory.getId());

                getVoMsg(vo, opDeliveryHistory);

                return vo;
            };
            return Result.ok((Page) page.convert(function));
        }
        return Result.ok(new Page<>());
    }

    private Boolean createGetUserListWrapper(LambdaQueryWrapper<OpDeliveryHistory> queryWrapper, SsDeliveryParam params) {
        //0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
        if (params.getState() != null) {
            if (params.getState() == 0) {
                queryWrapper.in(OpDeliveryHistory::getState, new Integer[]{0, 1});
            } else {
                queryWrapper.eq(OpDeliveryHistory::getState, params.getState());
            }
        }
        if (StringUtils.isNotBlank(params.getUserName())) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            infoQuery.like(PiInfo::getName, params.getUserName()).eq(PiInfo::getDelFlag, false);
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                piInfoList.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        if (params.getEduLevel() != null) {
            //0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA  7 博士
            LambdaQueryWrapper<CvUserEduInfo> eduQuery = new LambdaQueryWrapper<>();
            eduQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getEduLevel, params.getEduLevel());
            List<CvUserEduInfo> eduInfos = eduInfoService.list(eduQuery);
            if (CollectionUtils.isEmpty(eduInfos)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                eduInfos.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }
        }
        if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
            LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
            infoQuery.ge(PiInfo::getWorkYears, params.getMinWorkYear()).le(PiInfo::getWorkYears, params.getMaxWorkYear());
            List<PiInfo> piInfoList = piInfoService.list(infoQuery);
            if (CollectionUtils.isEmpty(piInfoList)) {
                return false;
            } else {
                List<String> userIds = new ArrayList<>();
                piInfoList.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
            }

        }
        return true;
    }

    private void getVoMsg(SsUserInfoVO vo, OpDeliveryHistory opDeliveryHistory) {
        LambdaQueryWrapper<CvUserEduInfo> eduQuery = new LambdaQueryWrapper<>();
        eduQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getUserId, opDeliveryHistory.getUserId()).orderByDesc(CvUserEduInfo::getEduLevel);
        List<CvUserEduInfo> eduInfos = eduInfoService.list(eduQuery);
        vo.setEduInfo(eduInfoConvert.toVO(eduInfos));
        OpJob job = jobService.getById(opDeliveryHistory.getJobId());
        vo.setJobName(job.getJobName());
        vo.setJob(jobConvert.toVO(job));
        vo.setJobTime(opDeliveryHistory.getCreateTime());
        vo.setJobId(job.getId());
        vo.setComId(job.getCompanyId());
        EnInfo enInfo = enInfoService.getById(job.getCompanyId());
        vo.setEnInfo(enInfoConvert.toVO(enInfo));
        vo.setDeliveryHistory(deliveryHistoryConvert.toVO(opDeliveryHistory));
        //入职记录
        OpEntryHistory entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).eq(OpEntryHistory::getUserId, opDeliveryHistory.getUserId()).eq(OpEntryHistory::getJobId, opDeliveryHistory.getJobId()).one();
        if (entryHistory != null) {
            vo.setEntryHistory(entryHistoryConvert.toVO(entryHistory));
            EnContacts enContacts = enContactsService.getById(entryHistory.getContactId());
            vo.getEntryHistory().setContact(contactsConvert.toVO(enContacts));
        }
        //面试信息
        List<OpInterviewHistory> list = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).eq(OpInterviewHistory::getJobId, opDeliveryHistory.getJobId()).eq(OpInterviewHistory::getUserId, opDeliveryHistory.getUserId()).orderByDesc(OpInterviewHistory::getCreateTime).list();
        vo.setOpInterviewHistory(interviewHistoryConvert.toVO(list));
        if (!CollectionUtils.isEmpty(vo.getOpInterviewHistory())) {
            vo.getOpInterviewHistory().forEach(i -> {
                if (i.getTime() != null) {
                    //面试时间是已过 true 是 false 否
                    i.setTimeFlag(System.currentTimeMillis() > i.getTime().getTime());
                }
                EnContacts enContacts1 = enContactsService.getById(i.getContactId());
                i.setContact(contactsConvert.toVO(enContacts1));

                List<OpInterviewContact> contact = contactService.lambdaQuery().eq(OpInterviewContact::getDelFlag, false).eq(OpInterviewContact::getViewId, i.getId()).list();
                if (!CollectionUtils.isEmpty(contact)) {
                    List<PiInfo> contacts = contact.stream().map(el -> piInfoService.lambdaQuery().eq(PiInfo::getUserId, el.getContactId()).one()).filter(el -> el != null).collect(Collectors.toList());
                    i.setConInfo(enPiInfoConvert.toVO(contacts));
                }

            });
        }
        //简历信息
        CvResume resume = resumeService.getById(opDeliveryHistory.getResumeId());
        List<CvResumeVO> resumevos = new ArrayList<>();
        resumevos.add(resumeConvert.toVO(resume));
        vo.setCvResumeList(resumevos);
        //个人信息
        PiInfo piInfo = piInfoService.lambdaQuery().eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, opDeliveryHistory.getUserId()).one();
        vo.setUserInfo(enPiInfoConvert.toVO(piInfo));
        List<CvUserWorkInfo> workInfos = workInfoService.lambdaQuery().eq(CvUserWorkInfo::getDelFlag, false).eq(CvUserWorkInfo::getUserId, opDeliveryHistory.getUserId()).orderByDesc(CvUserWorkInfo::getCreateTime).list();
        vo.setWorkInfo(workInfoConvert.toVO(workInfos));
        vo.setReId(opDeliveryHistory.getResumeId());
        List<CvWorkIntention> workIntentions = workIntentionService.lambdaQuery().eq(CvWorkIntention::getDelFlag, false).eq(CvWorkIntention::getUserId, opDeliveryHistory.getUserId()).list();
        vo.setWorkIntention(workIntentionConvert.toVO(workIntentions));
    }

}
